﻿using System;
using System.Net.NetworkInformation;
using System.Security.Cryptography;
using System.Text;
#if UNITY_IOS && !UNITY_EDITOR
using System.Runtime.InteropServices;
#endif
using UnityEngine;

namespace BToolkit
{
    /// <summary>
    /// 操作系统类型
    /// </summary>
    public enum EOSType
    {
        Unknown = 0,                // 未知
        Windows = 1,                // 微软PC
        MacBook = 2,                // 苹果笔记本
        Android = 3,                // 安卓手机
        AndroidPad = 4,             // 安卓平板
        iPhone = 5,                 // 苹果手机
        iPad = 6,                   // 苹果平板
        AndroidEmulator = 7,        // 安卓模拟器

        WindowsH5 = 8,              // 微软PC-H5
        MacBookH5 = 9,              // 苹果笔记本-H5
        AndroidH5 = 10,             // 安卓手机-H5
        AndroidPadH6 = 11,          // 安卓平板-H5
        iPhoneH5 = 12,              // 苹果手机-H5
        iPadH5 = 13,                // 苹果平板-H5

        CustomerService = 14,       // 客服客户端
    }

    public class SystemHelper
    {
        public enum InternetStatus
        {
            NoNet,
            Wifi,
            Mobile
        }
        public enum InternetQuality
        {
            Low,
            Middle,
            Hight
        }

        private static string deviceId;

        /// <summary>
        /// Android SDK版本（如29，30）
        /// </summary>
        public static int GetAndroidSDKVersion()
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            AndroidJavaClass jc = new AndroidJavaClass("cn.helper.SystemHelper");
            return jc.CallStatic<int>("getBatteryPercent");
#else
            return 0;
#endif
        }

        /// <summary>
        /// 获取当前电量的百分比（0-100的整数）
        /// </summary>
        public static int GetBatteryPercent()
        {
#if UNITY_EDITOR
            return 100;
#elif UNITY_ANDROID
            AndroidJavaClass jc = new AndroidJavaClass("cn.helper.SystemHelper");
            return jc.CallStatic<int>("getBatteryPercent");
#elif UNITY_IOS
            return (int)(_GetBatteryProgress() * 100);
#else
            return 0;
#endif
        }

        /// <summary>
        /// 获取当前网络类型
        /// </summary>
        public static InternetStatus GetInternetType()
        {
#if UNITY_EDITOR
            return InternetStatus.Wifi;
#elif UNITY_ANDROID
            AndroidJavaClass jc = new AndroidJavaClass("cn.helper.SystemHelper");
            string statusStr = jc.CallStatic<string>("getInternetType");
            switch (statusStr)
            {
                case "Wifi":
                    return InternetStatus.Wifi;
                case "Mobile":
                    return InternetStatus.Mobile;
                case "NoNet":
                    return InternetStatus.NoNet;
            }
            return InternetStatus.NoNet;
#elif UNITY_IOS
            string statusStr = _GetInternetStatus();
            switch (statusStr)
            {
                case "Wifi":
                    return InternetStatus.Wifi;
                case "CellularNetwork":
                    return InternetStatus.Mobile;
                case "NoNet":
                    return InternetStatus.NoNet;
            }
            return InternetStatus.NoNet;
#endif
        }

        /// <summary>
        /// 获取是否是Android模拟器
        /// </summary>
        public static bool IsAndroidSimulator()
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            AndroidJavaClass jc = new AndroidJavaClass("cn.helper.SystemHelper");
            return jc.CallStatic<bool>("isSimulator");
#else
            return false;
#endif
        }

        /// <summary>
        /// 获取是否是平板设备
        /// </summary>
        public static bool IsPad()
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            float physicscreen = Mathf.Sqrt(Screen.width * Screen.width + Screen.height * Screen.height) / Screen.dpi;
            return physicscreen >= 7f;
#elif UNITY_IOS && !UNITY_EDITOR
            string genneration = UnityEngine.SystemInfo.deviceModel.ToString();
            return genneration.ToLower().Substring(0, 3) == "ipad";
#else
            return false;
#endif
        }

        /// <summary>
        /// 获取系统时区ID（如：微软时区数据库返回"China Standard Time"，IANA/奥尔森时区数据库返回"Asia/Shanghai"，必要时需做两种适配）
        /// </summary>
        public static string GetSysTimeZoneID()
        {
#if UNITY_EDITOR
            return TimeZoneInfo.Local.Id;
#elif UNITY_ANDROID
            AndroidJavaClass jc = new AndroidJavaClass("cn.helper.SystemHelper");
            return jc.CallStatic<string>("getSysTimeZoneID");
#else
            
            return "Asia/Shanghai";
#endif
        }

        /// <summary>
        /// 获取系统时区Name（如：GMT+08:00）
        /// </summary>
        public static string GetSysTimeZoneName()
        {
#if UNITY_EDITOR
            if (TimeZoneInfo.Local.BaseUtcOffset.Hours < 0)
            {
                string h = TimeZoneInfo.Local.BaseUtcOffset.Hours.ToString("d2");
                string m = (-TimeZoneInfo.Local.BaseUtcOffset.Minutes).ToString("d2");
                return $"GMT{h}:{m}";
            }
            else
            {
                string h = TimeZoneInfo.Local.BaseUtcOffset.Hours.ToString("d2");
                string m = TimeZoneInfo.Local.BaseUtcOffset.Minutes.ToString("d2");
                return $"GMT+{h}:{m}";
            }
#elif UNITY_ANDROID
            AndroidJavaClass jc = new AndroidJavaClass("cn.helper.SystemHelper");
            return jc.CallStatic<string>("getSysTimeZoneName");
#else
            
            return "GMT+08:00";
#endif
        }

        /// <summary>
        /// 获取设备ID(仅在Unity主线程可取)
        /// </summary>
        public static string GetDeviceID(bool upperCase = true)
        {
            if (!string.IsNullOrEmpty(deviceId)) return deviceId;

#if UNITY_EDITOR
            NetworkInterface[] nice = NetworkInterface.GetAllNetworkInterfaces();
            foreach (NetworkInterface adaper in nice)
            {
                deviceId = adaper.GetPhysicalAddress().ToString() + "1";
                if (!string.IsNullOrEmpty(deviceId))
                {
                    deviceId = MD5(deviceId, upperCase);
                    return deviceId;
                }
            }
            return null;
#elif UNITY_ANDROID
            AndroidJavaClass jc = new AndroidJavaClass("cn.helper.SystemHelper");
            deviceId = MD5(jc.CallStatic<string>("getDeviceID"), upperCase);
            return deviceId;
#elif UNITY_IOS
            string iosPackName = AppHelper.GetAppPackageName();
            deviceId = MD5(_GetDeviceId(iosPackName), upperCase);
            return deviceId;
#else
            deviceId = MD5(UnityEngine.SystemInfo.deviceUniqueIdentifier, upperCase);
            return deviceId;
#endif
        }

        /// <summary>
        /// 安装Apk
        /// </summary>
        public static void InstallApk(string apkPath)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            AndroidJavaClass jc = new AndroidJavaClass("cn.helper.SystemHelper");
            jc.CallStatic("installApk", apkPath);
#endif
        }

        private static string MD5(string inputStr, bool upperCase)
        {
            byte[] inputBytes = Encoding.UTF8.GetBytes(inputStr);
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] hash = md5.ComputeHash(inputBytes);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                if (upperCase)
                {
                    sb.Append(hash[i].ToString("X2"));//字母大写
                }
                else
                {
                    sb.Append(hash[i].ToString("x2"));//字母小写
                }
            }
            return sb.ToString();
        }

        public static EOSType OSType
        {
            get
            {
#if UNITY_EDITOR
                return EOSType.Windows;
#elif UNITY_ANDROID
                if (IsAndroidSimulator())
                {
                    return EOSType.AndroidEmulator;
                }
                else
                {
                    if (IsPad())
                    {
                        return EOSType.AndroidPad;
                    }
                    else
                    {
                        return EOSType.Android;
                    }
                }
#elif UNITY_IOS || UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
                if (IsPad())
                {
                    return EOSType.iPad;
                }
                else
                {
                    return EOSType.iPhone;
                }
#elif UNITY_STANDALONE_WIN
                return EOSType.Windows;
#elif UNITY_STANDALONE_OSX
                return EOSType.MacBook;
#endif
            }
        }

#if UNITY_IOS && !UNITY_EDITOR
        [DllImport("__Internal")]
        static extern float _GetBatteryProgress();
        [DllImport("__Internal")]
        static extern string _GetInternetStatus();
        [DllImport("__Internal")]
        static extern string _GetDeviceId(string iosPackgeName);
#endif

    }
}